weex 扩展Android 和 iso 的能力


weex 扩展Android 和 iso 的能力, 来自weex官网

Module 扩展

  1. Module 扩展必须继承WXModule类。
  2. 扩展方法必须加上@JSMethod(uiThread = false or true)注解。Weex会根据注解来判断当前方法是否要运行在UI线程。
  3. Weex是根据反射来调用Module扩展方法,所以Module中的扩展方法必须是pulic类型。
  4. 同样是因为反射调用,Module不能被混淆。请在混淆文件中添加代码:-keep public class * extends com.taobao.weex.common.WXModule{*;}
  5. Module扩展方法可以使用int,double,float,String,Map,List类型的参数。
  6. 完成Module后一定要在初始化注册WXSDKEngine.registerModule("myModule", MyModule.class),否则会报类似错误:ReportException :undefined:9: TypeError: Object #<Object> has no method 'printLog';

示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
pulic class MyModule extends WXModule {
// run ui thread
@JSMethod(uithead = true)
public void printLog(String str) {
Toast.makeText(mWXSDKInstance.getContext(),msg,Toast.LENGTH_SHORT).show();
}

// run JS thread
@JSMethod(uiThread = false)
public void fireEventSyncCall() {
// implement your module logic here
}
}

Register the module

1
WXSDKEngine.registerModule('MyModule', MyModule.class);

JS调用如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<template>
<div>
<text onclick='click'>testMyModule</text>
</div>
</template>
<script>
export default {
name: ''.
methods: {
click() {
weex.requireModule('MyModule').printLog("i am a weex Module");
}
}
}
</script>

Module 注册

registerModule(moduleName,moduleClass)

  • return {bool}: 是否注册成功
  • moduleName {String}: 模块名称
  • moduleClass {Class}: 模块对应的class,创建module 实例时调用

使用方式:

1
WXSDKEngine.registerModule('picker', WXPickersModule.class);

Component 扩展(version< 0.19.0)

  • Component 扩展类必须继承 WXComponent.
  • Component 对应的设置属性的方法必须添加注解 @WXComponentProp(name=value(value is attr or style of dsl))
  • Weex sdk 通过反射调用对应的方法,所以 Component 对应的属性方法必须是 public,并且不能被混淆。请在混淆文件中添加代码-keep public class * extends com.taobao.weex.ui.component.WXComponent{*;}
  • Component 扩展的方法可以使用 int, double, float, String, Map, List 类型的参数
  • 完成 Component 后一定要在初始化时注册 WXSDKEngine.registerComponent("richText", RichText.class);
    示例如下:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    public class RichText extends WXComponent<TextView> {
    public RichText(WXSDKInstance instance, WXDomObject dom, WXContainer parent) {
    super(instance, dom, parent);
    }
    @Override
    protected TextView initComponentHostView(@NonNull Context context) {
    TextView textView = new TextView(context);
    textView.setTextSize(20);
    textView.setTextColor(Color.banck);
    return textView;
    }

    @WXComponentProp(name = "tel")
    public void setTel(String telNumber) {
    getHostView().setText("tel:" + telNumber);
    }
    }

注册你的组件:

1
WXSDKEngine.registerComponent('RichText', RichText.class);

JS调用如下:

1
2
3
4
5
<template>
<div>
<richText tel="12305" style="width:200;height:100">12305</richText>
</div>
</template>

Component 注册

registerComponent(type,class,appendTree)

  • return(bool): 是否注册成功
  • type(String): 前端使用的对应标签
  • class(Class): 组件的class,在创建组件实例时调用
  • appendTree(bool): 渲染时判定逻辑,默认false
    • 如果为true,则这个组件的子组件,整颗树建立、layout完后,整体一起刷新。
    • 如果为false,则这个组件的子组件,每add一个,刷新一个。
      使用方式:
      1
      WXSDKEngine.registerComponent('video', WXVideo, false);

registerComponent(holder,appendTree,…names)

  • return(bool): 是否注册成功
  • holder(IFComponentHolder): 用于创建component的抽象工厂,默认使用SimpleComponentHolder
  • appendTree: 同上
  • names(String …): 前端使用的对应标签
    使用方式:
    1
    2
    3
    4
    5
    6
    7
    8
    WXSDKEngine.registerComponent(
    new SimpleComponentHolder(
    WXText.class,
    new WXText.Creator()
    ),
    false,
    "text"
    );

Adapter 扩展

图片库Adapter

需要时集成接口 IWXImgLoaderAdapter,实现 setImage 方法。
示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class ImageAdapter implements IWXImgLoaderAdapter {

public ImageAdapter() {
}

@Override
public void setImage(final String url, final ImageView view,
WXImageQuality quality, WXImageStrategy strategy) {

WXSDKManager.getInstance().postOnUiThread(new Runnable() {

@Override
public void run() {
if(view==null||view.getLayoutParams()==null){
return;
}
if (TextUtils.isEmpty(url)) {
view.setImageBitmap(null);
return;
}
String temp = url;
if (url.startsWith("//")) {
temp = "http:" + url;
}
if (view.getLayoutParams().width <= 0 || view.getLayoutParams().height <= 0) {
return;
}
Picasso.with(WXEnvironment.getApplication())
.load(temp)
.into(view);
}
},0);
}
}

Adapter 注册

WEEX和图片库完全解耦,WEEX的图片加载,都是通过调用公共接口,由实现类决定调用哪个图片库

一个相对完整的源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
package com.alibaba.weex;

import android.app.Activity;
import android.app.Application;
import android.os.Bundle;

import com.alibaba.android.bindingx.plugin.weex.BindingX;
import com.alibaba.weex.commons.adapter.DefaultWebSocketAdapterFactory;
import com.alibaba.weex.commons.adapter.ImageAdapter;
import com.alibaba.weex.commons.adapter.JSExceptionAdapter;
import com.alibaba.weex.commons.adapter.PicassoBasedDrawableLoader;
import com.alibaba.weex.extend.adapter.ApmGenerator;
import com.alibaba.weex.extend.adapter.DefaultAccessibilityRoleAdapter;
import com.alibaba.weex.extend.adapter.InterceptWXHttpAdapter;
import com.alibaba.weex.extend.adapter.WXAnalyzerDemoListener;
import com.alibaba.weex.extend.component.WXComponentSyncTest;
import com.alibaba.weex.extend.component.WXMask;
import com.alibaba.weex.extend.component.WXParallax;
import com.alibaba.weex.extend.module.GeolocationModule;
import com.alibaba.weex.extend.module.MyModule;
import com.alibaba.weex.extend.module.RenderModule;
import com.alibaba.weex.extend.module.SyncTestModule;
import com.alibaba.weex.extend.module.WXEventModule;
import com.alibaba.weex.extend.module.WXTitleBar;
import com.alibaba.weex.extend.module.WXWsonTestModule;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.taobao.weex.InitConfig;
import com.taobao.weex.WXEnvironment;
import com.taobao.weex.WXSDKEngine;
import com.taobao.weex.WXSDKManager;
import com.taobao.weex.bridge.WXBridgeManager;
import com.taobao.weex.common.WXException;
import com.taobao.weex.performance.WXAnalyzerDataTransfer;

public class WXApplication extends Application {

@Override
public void onCreate() {
super.onCreate();

/**
* Set up for fresco usage.
* Set<RequestListener> requestListeners = new HashSet<>();
* requestListeners.add(new RequestLoggingListener());
* ImagePipelineConfig config = ImagePipelineConfig.newBuilder(this)
* .setRequestListeners(requestListeners)
* .build();
* Fresco.initialize(this,config);
**/
// initDebugEnvironment(true, false, "DEBUG_SERVER_HOST");
WXBridgeManager.updateGlobalConfig("wson_on");
WXEnvironment.setOpenDebugLog(true);
WXEnvironment.setApkDebugable(true);
WXSDKEngine.addCustomOptions("appName", "WXSample");
WXSDKEngine.addCustomOptions("appGroup", "WXApp");
WXSDKEngine.initialize(this,
new InitConfig.Builder()
//.setImgAdapter(new FrescoImageAdapter())// use fresco adapter
.setImgAdapter(new ImageAdapter())
.setDrawableLoader(new PicassoBasedDrawableLoader(getApplicationContext()))
.setWebSocketAdapterFactory(new DefaultWebSocketAdapterFactory())
.setJSExceptionAdapter(new JSExceptionAdapter())
.setHttpAdapter(new InterceptWXHttpAdapter())
.setApmGenerater(new ApmGenerator())
.build()
);
WXSDKManager.getInstance().addWXAnalyzer(new WXAnalyzerDemoListener());
WXAnalyzerDataTransfer.isOpenPerformance = false;

WXSDKManager.getInstance().setAccessibilityRoleAdapter(new DefaultAccessibilityRoleAdapter());

try {
Fresco.initialize(this);
WXSDKEngine.registerComponent("synccomponent", WXComponentSyncTest.class);
WXSDKEngine.registerComponent(WXParallax.PARALLAX, WXParallax.class);

WXSDKEngine.registerModule("render", RenderModule.class);
WXSDKEngine.registerModule("event", WXEventModule.class);
WXSDKEngine.registerModule("syncTest", SyncTestModule.class);

WXSDKEngine.registerComponent("mask", WXMask.class);
WXSDKEngine.registerModule("myModule", MyModule.class);
WXSDKEngine.registerModule("geolocation", GeolocationModule.class);

WXSDKEngine.registerModule("titleBar", WXTitleBar.class);

WXSDKEngine.registerModule("wsonTest", WXWsonTestModule.class);

BindingX.register();

/**
* override default image tag
* WXSDKEngine.registerComponent("image", FrescoImageComponent.class);
*/

//Typeface nativeFont = Typeface.createFromAsset(getAssets(), "font/native_font.ttf");
//WXEnvironment.setGlobalFontFamily("bolezhusun", nativeFont);

} catch (WXException e) {
e.printStackTrace();
}

registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(Activity activity, Bundle bundle) {

}

@Override
public void onActivityStarted(Activity activity) {

}

@Override
public void onActivityResumed(Activity activity) {

}

@Override
public void onActivityPaused(Activity activity) {

}

@Override
public void onActivityStopped(Activity activity) {

}

@Override
public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {

}

@Override
public void onActivityDestroyed(Activity activity) {
// The demo code of calling 'notifyTrimMemory()'
if (false) {
// We assume that the application is on an idle time.
WXSDKManager.getInstance().notifyTrimMemory();
}
// The demo code of calling 'notifySerializeCodeCache()'
if (false) {
WXSDKManager.getInstance().notifySerializeCodeCache();
}
}
});

}

/**
*@param connectable debug server is connectable or not.
* if true, sdk will try to connect remote debug server when init WXBridge.
*
* @param debuggable enable remote debugger. valid only if host not to be "DEBUG_SERVER_HOST".
* true, you can launch a remote debugger and inspector both.
* false, you can just launch a inspector.
* @param host the debug server host, must not be "DEBUG_SERVER_HOST", a ip address or domain will be OK.
* for example "127.0.0.1".
*/
private void initDebugEnvironment(boolean connectable, boolean debuggable, String host) {
if (!"DEBUG_SERVER_HOST".equals(host)) {
WXEnvironment.sDebugServerConnectable = connectable;
WXEnvironment.sRemoteDebugMode = debuggable;
WXEnvironment.sRemoteDebugProxyUrl = "ws://" + host + ":8088/debugProxy/native";
}
}

}